<template>
	<view class="circular-container" :style="{ width: boxWidth + 'px', height: boxHeight + 'px' }">
		<canvas
			class="circular-progress"
			type="2d"
			:id="canvasId"
			:style="{ width: boxWidth + 'px', height: boxHeight + 'px' }"
		></canvas>
		<slot></slot>
	</view>
</template>
<script>
	export default {
		name: 'LCircularProgress',
		props: {
			// 宽度
			boxWidth: {
				type: Number,
				default: 200,
			},
			//高度
			boxHeight: {
				type: Number,
				default: 200,
			},
			//进度条线条宽度
			lineWidth: {
				type: Number,
				default: 4,
			},

			//进度百分比
			percent: {
				type: Number,
				default: 0,
			},
			//进度条颜色
			progressColor: {
				type: String,
				default: '#5677fc',
			},
			//进度条渐变颜色
			gradualColor: {
				type: String,
				default: '',
			},
		},
		watch: {
			percent(newV, val) {
				if (newV && newV <= val) {
					this.progressContext && this.progressContext.clearRect(0, 0, this.boxWidth, this.boxHeight);
				}
				this.draw();
			},
		},
		mounted() {
			this.draw(true);
		},
		data() {
			return {
				canvasId: 'canvasId',
				progressContext: null,
				linearGradient: null,
			};
		},
		methods: {
			draw(init) {
				this.drawCircular();
			},

			//创建弧线
			drawArc(ctx, start, end) {
				ctx.lineCap = 'round';
				ctx.beginPath();
				let radius = this.boxWidth / 2;
				let lineWidth = Number(this.lineWidth);
				ctx.arc(radius, radius, radius - lineWidth, start, end, false);
				ctx.stroke();
			},
			//进度圆环
			async drawCircular(startPercent) {
				let ctx = this.progressContext;
				let gradient = this.linearGradient;
				if (!ctx) {
					// ctx = uni.createCanvasContext(this.canvasId, this);
					await new Promise(resolve => {
						uni.createSelectorQuery()
							.in(this)
							.select('#' + this.canvasId)
							.fields({
								node: true,
								size: true,
							})
							.exec(res => {
								const renderWidth = res[0].width;
								const renderHeight = res[0].height;
								const dpr = wx.getWindowInfo().pixelRatio;
								const canvas = res[0].node;
								ctx = canvas.getContext('2d');
								canvas.width = renderWidth * dpr;
								canvas.height = renderHeight * dpr;
								ctx.clearRect(0, 0, canvas.width, canvas.height);
								ctx.scale(dpr, dpr);
								resolve();
							});
					});

					let boxWidth = Number(this.boxWidth);
					gradient = ctx.createLinearGradient(0, 0, boxWidth, 0);
					gradient.addColorStop('0', this.progressColor);
					if (this.gradualColor) {
						gradient.addColorStop('1', this.gradualColor);
					}
					this.progressContext = ctx;
					this.linearGradient = gradient;
				}
				let lineWidth = Number(this.lineWidth);
				ctx.lineWidth = lineWidth;
				ctx.strokeStyle = gradient;
				let start = (-Math.PI * 4) / 3;
				let end = ((2 * Math.PI) / 100) * this.percent + start;
				if (this.percent > 0) {
					this.drawArc(ctx, start, end);
				}
			},
		},
	};
</script>
<style lang="scss" scoped>
	.circular-container {
		position: relative;
		.circular-progress {
			position: absolute;
			left: 0;
			top: 0;
			z-index: 999;
		}
	}
</style>
